# 算术运算符
a, b = 10, 3

puts a + b   # 加法 13
puts a - b   # 减法 7
puts a * b   # 乘法 30
puts a / b   # 除法 3 (整数除法)
puts a % b   # 取模 1
puts a ** b  # 幂运算 1000
puts -a      # 取负 -10

# 比较运算符
x, y = 5, 5.0

puts x == y   # 等于 true (值相等)
puts x.eql?(y) # 严格等于 false (类型不同)
puts x != y   # 不等于 false
puts x > y    # 大于 false
puts x < y    # 小于 false
puts x >= y   # 大于等于 true
puts x <= y   # 小于等于 true
puts x <=> y  # 太空船运算符 0 (相等返回0)

# 逻辑运算符
t, f = true, false

puts t && f   # 逻辑与 false
puts t || f   # 逻辑或 true
puts !t       # 逻辑非 false
puts t and f  # 低优先级与 false
puts t or f   # 低优先级或 true
puts not(t)   # 低优先级非 false
puts t ^ f    # 逻辑异或 true

puts "================================="

# 赋值运算符
a = 10
a += 5    # a = a + 5 → 15
a -= 3    # a = a - 3 → 12
a *= 2    # a = a * 2 → 24
a /= 4    # a = a / 4 → 6
a %= 5    # a = a % 5 → 1
a **= 3   # a = a ** 3 → 1

# 并行赋值
x, y, z = 1, 2, 3
x, y = y, x  # 交换值
puts x, y, z  # 输出: 2 1 3

puts "================================="

# 位运算符
a, b = 60, 13  # 二进制: 00111100, 00001101

puts a & b   # 按位与 12 (00001100)
puts a | b   # 按位或 61 (00111101)
puts a ^ b   # 按位异或 49 (00110001)
puts ~a      # 按位取补 -61 (11000011)
puts a << 2  # 左移 240 (11110000)
puts a >> 2  # 右移 15 (00001111)

puts "================================="

# 三元运算符
age = 20
status = age >= 18 ? "成人" : "未成年"
puts status  # 输出: 成人

puts "================================="

# 范围运算符

# 包含范围 (1..5)
(1..5).each { |n| print n }  # 输出: 12345

# 不包含范围 (1...5)
(1...5).each { |n| print n }  # 输出: 1234

# 检查包含
puts (1..10) === 5  # true
puts ('a'..'z') === 'm'  # true

puts "================================="

# defined? 运算符
var = 10
puts defined?(var)  # "local-variable"
puts defined?(nonexistent)  # nil

puts "================================="

# 安全导航运算符 &. (Ruby 2.3+)
user = nil
puts user&.name  # 输出nil而不报错

# user = OpenStruct.new(name: "Alice")
# puts user&.name  # 输出Alice

puts "================================="

# 匹配运算符 =~
puts "hello" =~ /ll/  # 返回匹配位置 2
puts /ll/ =~ "hello"  # 同样返回 2
puts "hello" =~ /xx/  # 不匹配返回nil

puts "================================="

# !~ 运算符
puts "hello" !~ /ll/  # false
puts "hello" !~ /xx/  # true

puts "================================="

# 运算符重载示例

# 定义一个向量类
class Vector
  # 定义属性访问器
  attr_accessor :x, :y

  # 初始化方法
  def initialize(x, y)
    @x = x
    @y = y
  end

  # 定义 + 运算符重载方法
  def +(other)
    Vector.new(@x + other.x, @y + other.y)
  end

  # 定义 to_s 方法，用于打印对象
  def to_s
    "(#{@x}, #{@y})"
  end
end

# 创建两个向量对象并相加
v1 = Vector.new(1, 2)
v2 = Vector.new(3, 4)
puts v1 + v2  # 输出: (4, 6)